package cn.sciento.oauth.api.controller.v1;

import cn.sciento.core.oauth.CustomUserDetails;
import cn.sciento.oauth.domain.entity.User;
import cn.sciento.oauth.security.custom.processor.logout.LogoutSuccessProcessor;
import cn.sciento.oauth.security.service.LoginRecordService;
import cn.sciento.oauth.security.service.UserAccountService;
import cn.sciento.swagger.annotation.Permission;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@RestController("v1.LogoutController")
@RequestMapping("token/logout")
public class LogoutController {

    private static final Logger LOGGER = LoggerFactory.getLogger(LogoutController.class);


    private TokenStore tokenStore;
    private UserAccountService userAccountService;
    private LoginRecordService loginRecordService;
    private List<LogoutSuccessProcessor> logoutProcessors;


    public LogoutController(TokenStore tokenStore, UserAccountService userAccountService, LoginRecordService loginRecordService, List<LogoutSuccessProcessor> logoutProcessors){
        this.tokenStore = tokenStore;
        this.userAccountService = userAccountService;
        this.loginRecordService = loginRecordService;
        this.logoutProcessors = logoutProcessors;
    }

    @PostMapping(value = "")
    @ApiOperation("退出")
    @Permission(permissionPublic = true)
    public ResponseEntity<?> storeClientTenant(@RequestParam("access_token") String accessToken,
                                               HttpServletRequest request,
                                               HttpServletResponse response) {
        OAuth2Authentication authentication = tokenStore.readAuthentication(accessToken);
        if(authentication == null){
            return ResponseEntity.ok(HttpEntity.EMPTY);
        }
        // 查询登出用户
        Object principal = authentication.getPrincipal();
        if (principal instanceof CustomUserDetails) {
            CustomUserDetails details = (CustomUserDetails) principal;
            User logoutUser = userAccountService.findLoginUser(details.getUserId());
            loginRecordService.saveLocalLoginUser(logoutUser);
        }

        // 处理器处理
        for (LogoutSuccessProcessor processor : logoutProcessors) {
            try {
                processor.process(request, response);
            } catch (Exception e) {
                LOGGER.error("logout processor error, processor is {}, ex={}",
                        processor.getClass().getSimpleName(), e.getMessage(), e);
            }
        }
        return ResponseEntity.ok(HttpEntity.EMPTY);
    }
}
